import socket
import threading

from handler import BaseHandler
from utils import logging
from protocol import Protocol, TEXT_MESSAGE, FILE_MESSAGE, JSON_MESSAGE


class TCPClient(object):

    def __init__(self, host: str, port: int, handler_cls):

        self.server_address = (host, port)
        self.handler_cls = handler_cls

        self.__socket: socket.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.__is_shutdown: bool = True



    def connect(self):
        self.__is_shutdown = False

        try:
            self.__socket.connect(self.server_address)
        except ConnectionRefusedError:
            self.node_disconnection()
            logging.info("连接服务器失败, 请检查地址和端口")

            return

        # 启动监听, 监听响应的信息
        threading.Thread(target=self.rece_message).start()

    def rece_message(self):
        self.handler: BaseHandler = self.handler_cls(self.__socket, self.server_address, self)
        while self.is_run:

            try:
                request: Protocol = Protocol.handler(self.handler.buff)

                if request is None:
                    continue

                if request.body == b'':
                    self.handler.on_connect_err('ConnectionResetError', descriotion="远程主机主动断开连接")

                    break

            except ConnectionResetError:
                """
                异常处理, ConnectionResetError 远程主机主动断开连接
                该异常是对方主动与我方断开连接, 
                """

                self.handler.on_connect_err('ConnectionResetError', descriotion="远程主机主动断开连接")

                break

            except ConnectionAbortedError:
                """
                异常处理, ConnectionAbortedError 你的主机中软件终止了一个已建立的连接
                该异常是我方主动与对方断开连接, 
                """

                self.handler.on_connect_err('ConnectionAbortedError', descriotion="你的主机中软件终止了一个已建立的连接")

                break

            except:
                """
                异常处理, 奇奇怪怪的异常处理,
                该异常处理其他异常
                """
                self.handler.on_connect_err('OtherError', descriotion="异常处理, 奇奇怪怪的异常处理")

                break

            self.handler.on_message(request)

        self.node_disconnection()

        return False

    def send(self, protocol: Protocol):
        """

        :param protocol:
        :return:
        """
        try:
            self.handler.send(protocol)
        except Exception:
            self.handler.on_connect_err('OtherError', descriotion="异常处理, 奇奇怪怪的异常处理")

            self.node_disconnection()
            return

    def node_disconnection(self, address=None):
        self.__is_shutdown = True

        try:
            self.__socket.close()
        except Exception:
            pass

    @property
    def is_run(self):
        return not self.__is_shutdown


class SimpleHandler(BaseHandler):

    def before_request_middleware(self, request: Protocol) -> bool:
        if request.header.get("test") and request.header.get("test") == "Test Header":
            return True
        return False

    def text_handler(self, request: Protocol):
        print("type: ", request.type)
        print("version: ", request.version)
        print("header: ", request.header)
        print(request.body.decode("utf-8"))

    def json_handler(self, request: Protocol):
        pass

    def file_handler(self, request: Protocol):
        pass


if __name__ == '__main__':
    client = TCPClient("127.0.0.1", 8848, handler_cls=SimpleHandler)
    client.connect()

    while client.is_run:
        data = input()

        if data == "exit":
            client.node_disconnection()
            break

        p = Protocol(TEXT_MESSAGE, data)
        p.set_header("test", "Test Header")

        client.send(p)
